package com.zrc.japktool.apk.jiagu;

import com.zrc.japktool.apk.merge.manifest.ManifestXmlEditor;
import com.zrc.japktool.apk.zipalignsign.Apk4kAligner;
import com.zrc.japktool.apk.zipalignsign.ApkSign;
import com.zrc.japktool.apk.zipalignsign.zipalign.ZipAlign;
import com.zrc.japktool.util.*;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class JiaGU {

    public static void jiGu(String inApkPath,TaskLog log){
        try {
            log.info("apk加固: 开始...");
            String jg_inApkPath = inApkPath;
            File jg_inApkFile = new File(jg_inApkPath);
            File jg_workSpeceFile = jg_inApkFile.getParentFile();
            String jg_workSpecePath = jg_workSpeceFile.getPath().replace("\\","/");
            String jg_inApkName = jg_inApkFile.getName().replace(".apk","");
            String jg_outApkPath = jg_workSpecePath + "/" + jg_inApkName+"-jg.apk";
            //Files.copy(Paths.get(jg_inApkPath),Paths.get(jg_outApkPath));
            FileUtil.copyFile(jg_inApkPath,jg_outApkPath);
            File jg_outApkFile = new File(jg_outApkPath);


            //从aar中读取so
            byte[] soByte = FileUtil.getResourceAsBytes("common/arm64-v8a/libjg.so");
            Zip4jUtil.writeFileBytes(jg_outApkPath, "lib/arm64-v8a/libjg.so", soByte,true);

            // 1. 修改AndroidManifest.xml（逻辑不变）
            ManifestXmlEditor manifestXmlEditor = new ManifestXmlEditor(jg_outApkPath);
            String apkApplicationPackge = manifestXmlEditor.getAppNameValue();
            String keApplicationPackge = "android.app.JgApplication";
            if (apkApplicationPackge == null) {
                apkApplicationPackge = "android.app.Application";
            }
            manifestXmlEditor.modifiyAppNameValue(keApplicationPackge, true);
            manifestXmlEditor.deleteAppComponentFactory();
            manifestXmlEditor.save2ApkFile(jg_outApkPath);
            log.info("apk加固: 已修改AndroidManifest中的Application名称为 " + keApplicationPackge);

            // 2. 获取并删除APK中的Dex文件（逻辑不变）
            List<byte[]> dexList = JGFileUtil.getApkDexBytes(jg_outApkPath);
            if (dexList.isEmpty()) {
                log.error("apk加固: 严重警告,未找到任何Dex文件，后续操作可能失败！");
            }

            // 3. 将lib.jg放入APK的assets目录：指定完整目标路径（assets/lib.jg）
            byte[] jgbyte =  JGFileUtil.createJGFile(apkApplicationPackge, dexList);
            Zip4jUtil.writeFileBytes(jg_outApkPath, "assets/lib.jg", jgbyte,false);
            log.info("apk加固: 已将lib.jg添加到APK的assets目录（目标路径：assets/lib.jg）");

            // 4. 添加壳的classes.dex
            byte[] kedexByte = FileUtil.getResourceAsBytes("common/classes.dex");
            Zip4jUtil.writeFileBytes(jg_outApkPath, "classes.dex", kedexByte,false);
            log.info("apk加固: 已添加壳的classes.dex到APK");

            // 5. 对齐（ZipAlign会自动确保resources.arsc以未压缩方式存储）
            String ziplan_inApkName = jg_outApkFile.getName().replace(".apk", "").replace("\\", "/");
            String ziplan_inApkPath = jg_outApkPath;
            File ziplan_inApkFile = new File(ziplan_inApkPath);
            File ziplan_outApkFile = new File(ziplan_inApkFile.getParent(), ziplan_inApkName + "-zipalign.apk");
            String ziplan_outApkPath = ziplan_outApkFile.getAbsolutePath().replace("\\", "/");
            Apk4kAligner apk4kAligner = new Apk4kAligner(log);
            apk4kAligner.zipAlign(ziplan_inApkPath, ziplan_outApkPath, false);
            //ZipAlign.zipAlign(ziplan_inApkPath, ziplan_outApkPath,log);

            // 6. 签名
            String sign_inApkPath = ziplan_outApkPath;
            File sign_inApkFile = new File(sign_inApkPath);
            String sign_outApkPath = new File(sign_inApkFile.getParent(), ziplan_inApkName + "-zipalign-sign.apk").getAbsolutePath().replace("\\", "/");

            ApkSign apkSign = new ApkSign(log);
            apkSign.sign1("123456", "key0", "123456", false, Paths.get(sign_inApkPath), Paths.get(sign_outApkPath));
//            if (jg_outApkFile.exists()) {
//                jg_outApkFile.delete();
//            }
//            if (ziplan_inApkFile.exists()) {
//                ziplan_inApkFile.delete();
//            }
//            if (ziplan_outApkFile.exists()) {
//                ziplan_outApkFile.delete();
//            }
            FileUtil.deleteFileWithRetry(jg_outApkPath);
            FileUtil.deleteFileWithRetry(ziplan_inApkPath);
            FileUtil.deleteFileWithRetry(ziplan_outApkPath);
            log.tip("apk加固: 成功...");
        } catch (Exception e) {
            log.error("apk加固: 失败..."+e.getMessage());
            e.printStackTrace();
        }finally {
            log.tip("apk加固: 结束...");
        }
    }

    public static void main(String[] args)throws Exception {
        TaskLog log = TaskLog.newTaskLog();
        try {
            File aar = new File("C:/Users/15666/IdeaProjects/JApkTool/doc/jiagu/JLib-debug.aar");
            File d8Jar = new File("C:/Users/15666/IdeaProjects/JApkTool/doc/jiagu/d8.jar");
            File classesZip = new File("C:/Users/15666/IdeaProjects/JApkTool/doc/jiagu/classes.zip");
            File classesJar = new File("C:/Users/15666/IdeaProjects/JApkTool/doc/jiagu/classes.jar");
            if (classesZip.exists()) {
                classesZip.delete();
            }
            if (classesJar.exists()) {
                classesJar.delete();
            }
            Zip4jUtil.extractFile(aar.getAbsolutePath().replace("\\","/"),"classes.jar",aar.getParent().replace("\\","/"));

            StringBuilder sb=new StringBuilder();
            sb.append("cmd /c  java -jar "+d8Jar.getAbsolutePath().replace("\\", "/"));
            //sb.append("--min-api 26 ");
            sb.append(" --output "+classesZip.getAbsolutePath().replace("\\","/"));
            sb.append(" "+classesJar.getAbsolutePath().replace("\\","/"));

            CmdUtil.exec(sb.toString(),log);

            byte[] kedexByte = Zip4jUtil.readFileBytes(classesZip.getPath(),"classes.dex");
            if (classesZip.exists()) {
                classesZip.delete();
            }
            if (classesJar.exists()) {
                classesJar.delete();
            }

            String jg_inApkPath = "C:/Users/15666/Desktop/test/yym.apk";
            File jg_inApkFile = new File(jg_inApkPath);
            File jg_workSpeceFile = jg_inApkFile.getParentFile();
            String jg_inApkName = jg_inApkFile.getName();
            String jg_outApkPath = "C:/Users/15666/Desktop/test/"+jg_inApkName+"_jg.apk";
            Files.copy(Paths.get(jg_inApkPath),Paths.get(jg_outApkPath));
            File jg_outApkFile = new File(jg_outApkPath);

            //从aar中读取so
            byte[] soByte = Zip4jUtil.readFileBytes(aar.getPath(),"jni/arm64-v8a/libjg.so");
            Zip4jUtil.writeFileBytes(jg_outApkPath, "lib/arm64-v8a/libjg.so", soByte,false);

            // 1. 修改AndroidManifest.xml（逻辑不变）
            ManifestXmlEditor manifestXmlEditor = new ManifestXmlEditor(jg_outApkPath);
            String apkApplicationPackge = manifestXmlEditor.getAppNameValue();
            String keApplicationPackge = "android.app.JgApplication";
            if (apkApplicationPackge == null) {
                apkApplicationPackge = "android.app.Application";
            }
            manifestXmlEditor.modifiyAppNameValue(keApplicationPackge, true);
            manifestXmlEditor.deleteAppComponentFactory();
            manifestXmlEditor.save2ApkFile(jg_outApkPath);
            log.info("已修改AndroidManifest中的Application名称为: " + keApplicationPackge);

            // 2. 获取并删除APK中的Dex文件（逻辑不变）
            List<byte[]> dexList = JGFileUtil.getApkDexBytes(jg_outApkPath);
            if (dexList.isEmpty()) {
                log.error("严重警告：未找到任何Dex文件，后续操作可能失败！");
            }

            // 3. 将lib.jg放入APK的assets目录：指定完整目标路径（assets/lib.jg）
            byte[] jgbyte =  JGFileUtil.createJGFile(apkApplicationPackge, dexList);
            Zip4jUtil.writeFileBytes(jg_outApkPath, "assets/lib.jg", jgbyte,false);
            log.info("已将lib.jg添加到APK的assets目录（目标路径：assets/lib.jg）");

            // 4. 添加壳的classes.dex
            Zip4jUtil.writeFileBytes(jg_outApkPath, "classes.dex", kedexByte,false);
            log.info("已添加壳的classes.dex到APK");

            // 5. 对齐
            String ziplan_inApkName = jg_outApkFile.getName().replace(".apk", "").replace("\\", "/");
            String ziplan_inApkPath = jg_outApkPath;
            File ziplan_inApkFile = new File(ziplan_inApkPath);
            File ziplan_outApkFile = new File(ziplan_inApkFile.getParent(), ziplan_inApkName + "-zipalign.apk");
            String ziplan_outApkPath = ziplan_outApkFile.getAbsolutePath().replace("\\", "/");
            //Apk4kAligner apk4kAligner = new Apk4kAligner(log);
            //apk4kAligner.zipAlign(ziplan_inApkPath, ziplan_outApkPath, false);
            ZipAlign.zipAlign(ziplan_inApkPath, ziplan_outApkPath,log);

            // 6. 签名
            String sign_inApkPath = ziplan_outApkPath;
            File sign_inApkFile = new File(sign_inApkPath);
            String sign_outApkPath = new File(sign_inApkFile.getParent(), ziplan_inApkName + "-zipalign-sign.apk").getAbsolutePath().replace("\\", "/");

            ApkSign apkSign = new ApkSign(log);
            apkSign.sign1("123456", "key0", "123456", false, Paths.get(sign_inApkPath), Paths.get(sign_outApkPath));
            if (jg_outApkFile.exists()) {
                jg_outApkFile.delete();
            }
            if (ziplan_inApkFile.exists()) {
                ziplan_inApkFile.delete();
            }
            if (ziplan_outApkFile.exists()) {
                ziplan_outApkFile.delete();
            }
            AdbUtil.installApk(sign_inApkFile,log);
        } catch (IOException e) {
            log.error("执行过程中发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
